/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jogl2.pkg0.project;

/**
 *
 * @author Peb
 */
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.fixedfunc.GLLightingFunc;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;


import com.jogamp.opengl.util.awt.TextRenderer;

import rnavizexperimentation.*;


import com.jogamp.opengl.util.Animator;
import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.LinkedList;

/**
 * ported to JOGL 2.0 by Julien Gouesse (http://tuer.sourceforge.net)
 */
public class Feymann_1cirkel2 implements GLEventListener, KeyListener {

    float rotateT = 0.0f;
    float cameraDistance = 350;
    float cameraPosX = 0;
    float cameraPosY = 0;
    int moveX = 0;
    int moveY = 0;
    static int indexNucleo1 = 4;
    static int indexNucleo2 = 14;
    static int feynmannCircleOriginX = 0;
    static int feynmannCircleOriginY = 0;
    static final int numberOfNucleotides = 50;
    static float feynmannCircleRadius = (numberOfNucleotides * 2 * 3.14f);
    static float offsetRadius = feynmannCircleRadius - 12.5f;
    float standardRadiusCircle = 300;
    float scaleX = standardRadiusCircle / feynmannCircleRadius;
    float scaleY = standardRadiusCircle / feynmannCircleRadius;
//    float scaleX = 0.125f;
//    float scaleY = 0.125f;
    private int startList;
    static GLU glu = new GLU();
    static GLCanvas canvas = new GLCanvas();
    static Frame frame = new Frame("Jogl Quad drawing");
    static Animator animator = new Animator(canvas);
    static Font font = new Font("serif", Font.PLAIN, 36);
    static TextRenderer textRenderer = new TextRenderer((font), true, true);

    public void display(GLAutoDrawable gLDrawable) {
        final GL2 gl = gLDrawable.getGL().getGL2();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl.glClear(GL.GL_DEPTH_BUFFER_BIT);

        // tegn coordinatsystem
        drawCoordinateSys(gl);

        gl.glLoadIdentity();





// the set camera thingy

        gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
        gl.glLoadIdentity();
        float widthHeightRatio = 1.0f;


        glu.gluPerspective(45, widthHeightRatio, 1, 1000);
        glu.gluLookAt(cameraPosX, cameraPosY, cameraDistance, 0, 0, 0, 0, 1, 0);

        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
        gl.glLoadIdentity();

// End camera thingy




//        gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);
//        rotateT += 0.1f;
//        glu.gluSphere(earth, 6.4f, 16, 16);

//        gl.glTranslatef(50, 50, 0);
        gl.glColor3f(0.3f, 0.2f, 1.0f);   // set the color of the quad



//        gl.glBegin(GL2.GL_TRIANGLE_FAN);
//        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
//        gl.glVertex3f(-2, -2, 0);       // Top Right
//        gl.glVertex3f(+2, -2, 0);      // Bottom Right
//        gl.glVertex3f(0, 20, 0);     // Bottom Left
//        gl.glEnd();



//        gl.glTranslatef(-20.0f, 0.0f, -135.0f);

        // rotate on the three axis
//        gl.glRotatef(rotateT, 1.0f, 0.0f, 0.0f);
//        gl.glRotatef(rotateT, 0.0f, 1.0f, 0.0f);
//        gl.glRotatef(rotateT, 0.0f, 0.0f, 1.0f);

//         Draw A Quad
//        gl.glBegin(GL2.GL_QUADS);
//        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
//        gl.glVertex3f(-1.0f, 1.0f, 0.0f);      // Top Left
//        gl.glVertex3f(1.0f, 1.0f, 0.0f);       // Top Right
//        gl.glVertex3f(1.0f, -1.0f, 0.0f);      // Bottom Right
//        gl.glVertex3f(-1.0f, -1.0f, 0.0f);     // Bottom Left
//         Done Drawing The Quad
//        gl.glEnd();



//        gl.glPushMatrix();
//        gl.glBegin(GL.GL_TRIANGLES);              // Begin drawing triangles
//        gl.glTranslatef(-1.5f,1.5f,-8.0f);        // Move left 1.5 units, up 1.5 units, and back 8 units

//================================

        gl.glScalef(scaleX, scaleY, 1.0f);




//        gl.glScalef(0.5f, 0.5f, 1.0f);

//        gl.glLoadIdentity(); //reset instillinger bla position for gl objektet




        textRenderer.setColor(Color.WHITE);
        textRenderer.begin3DRendering();

//        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);////////remove


//            gl.glLoadIdentity();


        for (Point2D_intw_degreeAnd_offset item : circleCoordinates) {
//        Point2D_intw_degree item = circleCoordinates[0];

//            gl.glLoadIdentity();


//            gl.glRotatef(rotateT, item.getX(), item.getX(), 1);

            int x = item.getX();
            int y = item.getY();
            float d = item.getDegree();

            gl.glTranslatef(x, y, 0);
//            gl.glRotatef(d, 0, 0, 1);


//            textRenderer.draw("d", item.getX() + move, item.getY() + move);
//            textRenderer.draw3D("A", item.getX() + moveX -12.5f, item.getY() + moveY -12.5f, -400.0f, 1.0f);
            textRenderer.draw3D("A", 0, 0, -550.0f, 1.0f);
            textRenderer.flush();

            //Revert matrix changes
//            gl.glRotatef(-d, 0, 0, 1);
            gl.glTranslatef(-x, -y, 0);




//        gl.glLoadIdentity();
//        gl.glTranslatef(20, 20, 0);
//        gl.glRotatef(180, 0, 0, 1);
//        textRenderer.draw3D("A", 0, 0, -400.0f, 1.0f);
//        textRenderer.flush();


        }


        textRenderer.flush();
//        gl.glPopMatrix();

        textRenderer.end3DRendering();



        //        move += 1;

//================================ Draw red line from origin to points on periferi

//        gl.glBegin(GL2.GL_LINES);
//        for (Point2D_intw_degreeAnd_offset item : circleCoordinates) {
//            gl.glColor3f(1.0f, 0.0f, 0.0f);   // set the color of x
//            gl.glVertex3f(item.getxOffset(), item.getyOffset(), -550);
//            gl.glVertex3f(0, 0, -550);
//        }
//        gl.glEnd();

//================================        


// Tegn arcs ======================================




        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
        GLUquadric earth = glu.gluNewQuadric();
        glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
        glu.gluQuadricNormals(earth, GLU.GLU_NONE);
        glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);


//        for (Point2D_int_wColor item : pointCoordinatesWColor) {
//            gl.glPushMatrix();
//            gl.glColor3f(item.getRandomFloatColor().getColor1(),
//                    item.getRandomFloatColor().getColor2(),
//                    item.getRandomFloatColor().getColor3());   // set the color of the quad
//            gl.glTranslatef(item.getX() * 1, item.getY() * 1, 0);
//            glu.gluPartialDisk(earth, 19.0, 20.0, 20, 1, 0.0, 225.0);
//            gl.glPopMatrix();
//        }
//        glu.gluDeleteQuadric(earth);


// End tegn arcs ===================================

//============================= arc

//        gl.glColor3f(1.0f, 1.0f, 1.0f);   // set the color of the quad
//        GLUquadric earth = glu.gluNewQuadric();
//        glu.gluQuadricDrawStyle(earth, GLU.GLU_FILL);
//        glu.gluQuadricNormals(earth, GLU.GLU_NONE);
//        glu.gluQuadricOrientation(earth, GLU.GLU_OUTSIDE);





//===================== Cirkel beregninger =====================================

        //Her starter trigonometri beregninger for buerne
        // Input, hvad skal methoden ha' at vide? 
        //1. koord for de to punkter 
        //2. centrum for feynman cirkel
        //3. hvor mange punkter der er i periferien (længden af array der indeholder punkterne 
        //4. de to punkters placering i array'et så det kan beregnes om de ligger over halvdelen af arrays længde
        //   fra hinanden -> dvs. om de ligger over 180 grader fra hinanden

        // Output:
        //1. circlex, circley (origin for halvcirklen)
        //2. arcRadius (radius for halvcirklen)
        //3. startAngle, sweep








//        int index = 25;


//        float p1x = circleCoordinates[index%(circleCoordinates.length-1)].getxOffset();
//        float p1y = circleCoordinates[index%(circleCoordinates.length-1)].getyOffset();
//
//        float p2x = circleCoordinates[(index%(circleCoordinates.length-1-8)) + 8].getxOffset();
//        float p2y = circleCoordinates[(index%(circleCoordinates.length-1-8)) + 8].getyOffset();


        float p1x = circleCoordinates[indexNucleo1].getxOffset();
        float p1y = circleCoordinates[indexNucleo1].getyOffset();

        float p2x = circleCoordinates[indexNucleo2].getxOffset();
        float p2y = circleCoordinates[indexNucleo2].getyOffset();


        System.out.println("Første punkt på Fcirkelen: " + p1x + ", " + p1y + " ;; Andet punkt: " + p2x + ", " + p2y);
        System.out.println("X,Y for Feynmann cirkels centrum: " + feynmannCircleOriginX + ", " + feynmannCircleOriginY);



        // --------------------------------------------------       

        //  Hvis vinklen imellem to nukleotider er mere end 180 grader skal der byttes om på de to punkter.
        //  Dette gøres ved at undersøge om afstanden mellem de to nukleotider er mere end halvdelen af 
        //  samtlige beregnede punkter på periferien af feynmann (eller offset) cirklen.


        if (indexNucleo2 - indexNucleo1 > circleCoordinates.length / 2) {

            System.out.println("Nu er den over 180 grader!!");

            float tempx = p1x;
            float tempy = p1y;

            p1x = p2x;
            p1y = p2y;

            p2x = tempx;
            p2y = tempy;


        }





        //------hældning linje 1
        float m1 = (p1y - (float) feynmannCircleOriginY) / (p1x - (float) feynmannCircleOriginX);

        //------hældning linje 2
        float m2 = (p2y - (float) feynmannCircleOriginY) / (p2x - (float) feynmannCircleOriginX);

        System.out.println("Hældning linje1: " + m1 + ";;; Hældning linje2: " + m2);



        //======================== Undersøg om de to linjer er tæt på parallelle og tegn linje hvis det er således.
        // Linjerne er helt parallelle hvis værdien er 0.0. Lige nu er værdien 0.05 arbitrært valgt
        // Måske skulle jeg undersøge om tangenterne var parallelle istedet. Jeg tror at nedenstående måske vil give
        // nogle fæle fejl...?
        // Der skal tegnes linjer hvis to nukelotider ligger lige overfor hinanden. Løsning kunne være at
        //  teste om tangenterne er parallele indenfor en vis tolerance og så tegne en linje istedet for en bue

        if (Math.abs(m1 - m2) <= 0.005f) {
            gl.glBegin(GL2.GL_LINES);
            gl.glColor3f(0.3f, 0.2f, 1.0f);
            gl.glVertex3f(p1x, p1y, -550);
            gl.glVertex3f(p2x, p2y, -550);
            gl.glEnd();
            System.out.println("HERE I DRAW THE LINE");

        } else {



            //=======================================




// ---------

            // beregner hældning for den vinkelrette tangent
//        m1 = -1 / m1;
//        m2 = -1 / m2;

            if (m1 == 0) {
                m1 = 9999;
            } else {
                m1 = -1 / m1;
            }


            if (m2 == 0) {
                m2 = 9999;
            } else {
                m2 = -1 / m2;
            }

//        float temp = Float.MAX_VALUE;
//        m2 = temp;


            System.out.println("Hældning tangent1: " + m1 + ";;;;; Hældning tangent2: " + m2);


            float b1 = p1y - (m1 * p1x);
            float b2 = p2y - (m2 * p2x);


            System.out.println("b1: " + b1 + " ;;; b2: " + b2);

            float circlex = (b2 - b1) / (m1 - m2);
            float circley = (m1 * circlex) + b1;


            System.out.println("Circlex: " + circlex + ", Circley: " + circley);

            // Pythagoras for at finde radius
            double arcRadius = Math.sqrt(((circlex - p1x) * (circlex - p1x)) + ((circley - p1y) * (circley - p1y)));


            // siden b er afstanden mellem centrum i cirkel i Feymnann(offset cirklen) og centrum for buecirklen
            // Afstanden mellem to punkter beregnes som: sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))

            double sideB = Math.sqrt(((feynmannCircleOriginX - circlex) * (feynmannCircleOriginX - circlex))
                    + ((feynmannCircleOriginY - circley) * (feynmannCircleOriginY - circley)));


            //======== Cosinus relation. Her brugt til at beregne vinklen A //sweep vinklen
            // A = cos^-1((b*b+c*c-a*a)/)2*b*c))


            double sweep = ((sideB * sideB) + (arcRadius * arcRadius)
                    - (offsetRadius * offsetRadius))
                    / (2 * sideB * arcRadius);

            sweep = Math.acos(sweep);
            sweep = Math.toDegrees(sweep);

            //husk at gange vinklen med 2
            sweep = sweep * 2;


            System.out.println("ArcRadius: " + arcRadius + "; CircleY-p1y= " + 2 * (circley - p1y) * (circley - p1y) + " ;;; sweep er lig med: " + sweep);


// Beregn startvinkel for sweep  =========================================================

            double psx = circlex;
            double psy = circley + arcRadius;


            double sideModsatStartvinkel = Math.sqrt(((psx - p1x) * (psx - p1x)) + ((psy - p1y) * (psy - p1y)));

            double startAngle = ((arcRadius * arcRadius) + (arcRadius * arcRadius)
                    - (sideModsatStartvinkel * sideModsatStartvinkel))
                    / (2 * arcRadius * arcRadius);



            if (startAngle < -1) {
                startAngle = -1;
            }
            startAngle = Math.acos(startAngle);
            startAngle = Math.toDegrees(startAngle);

// ================        



            System.out.println("StartAngle: " + startAngle);
            System.out.println("==============================================================================");




//======== Test om punkt1's y-værdi er mindre end centrums y-værdi.
// I så fald skal den beregnede vindes sættes til minus


            if (p1y < feynmannCircleOriginY) {
                startAngle = -(startAngle);
            }



//==== Draw

            gl.glTranslatef(circlex, circley, -550);

            gl.glColor3f(0.3f, 0.2f, 1.0f);   // set the color of the quad
            
            Arc_data a = arcArrayList.get(0);

//            glu.gluPartialDisk(earth, arcRadius, arcRadius + 1, 50, 2, startAngle, sweep);
            
            
            glu.gluPartialDisk(earth, a.getArcRadiusInner(), a.getArcRadiusOuter(), a.getSlices(),
                    a.getLoops(), a.getStartAngle(), a.getSweep());
            


//========================== arc end





        }




    }
// CalculateArcArray 
//--------------------------------------------------------------------------------------------------------    
//    private static Line_data [] lineArray;
//    private static Arc_data [] arcArray;
    private static ArrayList<Line_data> lineArrayList = new ArrayList<Line_data>();
    private static ArrayList<Arc_data> arcArrayList = new ArrayList<Arc_data>();
    //index for nuc 1 i 1. knude, index for nuc 2 i 1. knude, index for nuc 1 i 2. knude, index for nuc 2 i 2. knude..
    //... og så fremdeles.
    private static KnotTest[] randomKnotsArray = new KnotTest[1]; //new int[numberOfNucleotides/2];

    public static void calculateArcArray() {

        randomKnotsArray[0] = new KnotTest(4, 2);


//        for (KnotTest item : randomKnotsArray) {
        
        KnotTest item = randomKnotsArray[0];






//===================== Cirkel beregninger =====================================

            //Her starter trigonometri beregninger for buerne
            // Input, hvad skal methoden ha' at vide? 
            //1. koord for de to punkter 
            //2. centrum for feynman cirkel
            //3. hvor mange punkter der er i periferien (længden af array der indeholder punkterne 
            //4. de to punkters placering i array'et så det kan beregnes om de ligger over halvdelen af arrays længde
            //   fra hinanden -> dvs. om de ligger over 180 grader fra hinanden

            // Output:
            //1. circlex, circley (origin for halvcirklen)
            //2. arcRadius (radius for halvcirklen)
            //3. startAngle, sweep








//        int index = 25;


//        float p1x = circleCoordinates[index%(circleCoordinates.length-1)].getxOffset();
//        float p1y = circleCoordinates[index%(circleCoordinates.length-1)].getyOffset();
//
//        float p2x = circleCoordinates[(index%(circleCoordinates.length-1-8)) + 8].getxOffset();
//        float p2y = circleCoordinates[(index%(circleCoordinates.length-1-8)) + 8].getyOffset();


//            float p1x = circleCoordinates[indexNucleo1].getxOffset();
//            float p1y = circleCoordinates[indexNucleo1].getyOffset();
//            float p2x = circleCoordinates[indexNucleo2].getxOffset();
//            float p2y = circleCoordinates[indexNucleo2].getyOffset();
        
        
        int indexNuc1 = item.getIndexNuc1();
        int indexNuc2 = item.getIndexNuc2();
        
        

            float p1x = circleCoordinates[indexNuc1].getxOffset();
            float p1y = circleCoordinates[indexNuc1].getyOffset();

            float p2x = circleCoordinates[indexNuc2].getxOffset();
            float p2y = circleCoordinates[indexNuc2].getyOffset();




            System.out.println("Første punkt på Fcirkelen: " + p1x + ", " + p1y + " ;; Andet punkt: " + p2x + ", " + p2y);
            System.out.println("X,Y for Feynmann cirkels centrum: " + feynmannCircleOriginX + ", " + feynmannCircleOriginY);



            // --------------------------------------------------       

            //  Hvis vinklen imellem to nukleotider er mere end 180 grader skal der byttes om på de to punkter.
            //  Dette gøres ved at undersøge om afstanden mellem de to nukleotider er mere end halvdelen af 
            //  samtlige beregnede punkter på periferien af feynmann (eller offset) cirklen.


            if (indexNuc2 - indexNuc1 > circleCoordinates.length / 2) {

                System.out.println("Nu er den over 180 grader!!");

                float tempx = p1x;
                float tempy = p1y;

                p1x = p2x;
                p1y = p2y;

                p2x = tempx;
                p2y = tempy;


            }





            //------hældning linje 1
            float m1 = (p1y - (float) feynmannCircleOriginY) / (p1x - (float) feynmannCircleOriginX);

            //------hældning linje 2
            float m2 = (p2y - (float) feynmannCircleOriginY) / (p2x - (float) feynmannCircleOriginX);

            System.out.println("Hældning linje1: " + m1 + ";;; Hældning linje2: " + m2);



            //======================== Undersøg om de to linjer er tæt på parallelle og tegn linje hvis det er således.
            // Linjerne er helt parallelle hvis værdien er 0.0. Lige nu er værdien 0.05 arbitrært valgt
            // Måske skulle jeg undersøge om tangenterne var parallelle istedet. Jeg tror at nedenstående måske vil give
            // nogle fæle fejl...?
            // Der skal tegnes linjer hvis to nukelotider ligger lige overfor hinanden. Løsning kunne være at
            //  teste om tangenterne er parallele indenfor en vis tolerance og så tegne en linje istedet for en bue

            if (Math.abs(m1 - m2) <= 0.005f) {
                // her tegnedes før linjen.
                // Lægges nu ind i et linje array istedet.
                
                
                
                ColorRGB_data color = new ColorRGB_data(0.0f, 0.0f, 1.0f);
                lineArrayList.add(new Line_data(p1x, p2x, p1y, p2y, -550, -550, color));
                
                
                
//            gl.glBegin(GL2.GL_LINES);
//                gl.glColor3f(0.3f, 0.2f, 1.0f);
//                gl.glVertex3f(p1x, p1y, -550);
//                gl.glVertex3f(p2x, p2y, -550);
//            gl.glEnd();
//            System.out.println("HERE I DRAW THE LINE");
            } else {



                //=======================================




// ---------

                // beregner hældning for den vinkelrette tangent
//        m1 = -1 / m1;
//        m2 = -1 / m2;

                if (m1 == 0) {
                    m1 = 9999;
                } else {
                    m1 = -1 / m1;
                }


                if (m2 == 0) {
                    m2 = 9999;
                } else {
                    m2 = -1 / m2;
                }

//        float temp = Float.MAX_VALUE;
//        m2 = temp;


                System.out.println("Hældning tangent1: " + m1 + ";;;;; Hældning tangent2: " + m2);


                float b1 = p1y - (m1 * p1x);
                float b2 = p2y - (m2 * p2x);


                System.out.println("b1: " + b1 + " ;;; b2: " + b2);

                float circlex = (b2 - b1) / (m1 - m2);
                float circley = (m1 * circlex) + b1;


                System.out.println("Circlex: " + circlex + ", Circley: " + circley);

                // Pythagoras for at finde radius
                double arcRadius = Math.sqrt(((circlex - p1x) * (circlex - p1x)) + ((circley - p1y) * (circley - p1y)));


                // siden b er afstanden mellem centrum i cirkel i Feymnann(offset cirklen) og centrum for buecirklen
                // Afstanden mellem to punkter beregnes som: sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))

                double sideB = Math.sqrt(((feynmannCircleOriginX - circlex) * (feynmannCircleOriginX - circlex))
                        + ((feynmannCircleOriginY - circley) * (feynmannCircleOriginY - circley)));


                //======== Cosinus relation. Her brugt til at beregne vinklen A //sweep vinklen
                // A = cos^-1((b*b+c*c-a*a)/)2*b*c))


                double sweep = ((sideB * sideB) + (arcRadius * arcRadius)
                        - (offsetRadius * offsetRadius))
                        / (2 * sideB * arcRadius);

                sweep = Math.acos(sweep);
                sweep = Math.toDegrees(sweep);

                //husk at gange vinklen med 2
                sweep = sweep * 2;


                System.out.println("ArcRadius: " + arcRadius + "; CircleY-p1y= " + 2 * (circley - p1y) * (circley - p1y) + " ;;; sweep er lig med: " + sweep);


// Beregn startvinkel for sweep  =========================================================

                double psx = circlex;
                double psy = circley + arcRadius;


                double sideModsatStartvinkel = Math.sqrt(((psx - p1x) * (psx - p1x)) + ((psy - p1y) * (psy - p1y)));

                double startAngle = ((arcRadius * arcRadius) + (arcRadius * arcRadius)
                        - (sideModsatStartvinkel * sideModsatStartvinkel))
                        / (2 * arcRadius * arcRadius);



                if (startAngle < -1) {
                    startAngle = -1;
                }
                startAngle = Math.acos(startAngle);
                startAngle = Math.toDegrees(startAngle);

// ================        
//        double startAngle = 0;
//        sweep = 360;


                System.out.println("StartAngle: " + startAngle);
                System.out.println("==============================================================================");




//======== Test om punkt1's y-værdi er mindre end centrums y-værdi.
// I så fald skal den beregnede vindes sættes til minus


                if (p1y < feynmannCircleOriginY) {
                    startAngle = -(startAngle);
                }



//==== Draw

//            gl.glTranslatef(circlex, circley, -550);
//            gl.glColor3f(0.3f, 0.2f, 1.0f);   // set the color of the quad
//            glu.gluPartialDisk(earth, arcRadius, arcRadius + 1, 50, 2, startAngle, sweep);
                
                ColorRGB_data c = new ColorRGB_data(0.0f, 0.0f, 1.0f);
//                arcArrayList.add(new Arc_data(arcRadius, arcRadius+1, 50, 2, startAngle, sweep, c));



                //LÆG ARC DETALJER IND I ARRAY



//========================== arc end








//            }


        }



    }
// GetKnotArray (get the sequence number of the two 
//--------------------------------------------------------------------------------------------------------    
    private static Knot[] knotArray;
    static char[] sequence;
    static char[] knots;
    static LinkedList<Knot> edges;

    public static Knot[] getKnotArray() {

        InputHandler inp = new InputHandler();
        Structure si = inp.smallInput();
        sequence = si.getBaseSequence();
        knots = si.getDotSequence();

        edges = new LinkedList<Knot>();
        LinkedList<Knot> normalKnots = new LinkedList<Knot>();
        LinkedList<Knot> pseudoKnots = new LinkedList<Knot>();

        for (int i = 0; i < knots.length; i++) {
//            int x = 10 * i;
            if (knots[i] == '(') {
                Base n = new Base(i, sequence[i]);
                normalKnots.add(new Knot(new Base(i, sequence[i])));
                //drawArc(x, 100, 100, g2);
            }
            if (knots[i] == '[') {
                Base n = new Base(i, sequence[i]);
                pseudoKnots.add(new Knot(new Base(i, sequence[i])));
            }
            if (knots[i] == ')') {
                Base n = new Base(i, sequence[i]);
                Knot e = normalKnots.pop();
                e.setB2(n);
                edges.add(e);
            }
            if (knots[i] == ']') {
                Base n = new Base(i, sequence[i]);
                Knot e = pseudoKnots.pop();
                e.setB2(n);
                edges.add(e);
            }
        }


        while (!edges.isEmpty()) {
            Knot e = edges.pop();
            System.out.println(e.getB1().getPosition() + " - "
                    + e.getB1().getNucleotide() + "====" + e.getB2().getPosition() + " - " + e.getB2().getNucleotide());

//            int b1X = e.getB1().getX();
//            int e2X = e.getB2().getX();
//            drawArc(b1X,(e2X-b1X),100,g2);

        }


        return knotArray;
    }
//--------------------------------------------------------------------------------------------------------    
//    private static 
//--------------------------------------------------------------------------------------------------------    
    private static Point2D_intw_degreeAnd_offset[] circleCoordinates =
            new Point2D_intw_degreeAnd_offset[numberOfNucleotides];

    public static Point2D_intw_degreeAnd_offset[] calculateCoordCircle(int originx, int originy, int numberOfPoints, float radius) {


        for (int i = 0; i < numberOfPoints; i++) {
// Formlen for omregning er altså:  radianer = (2π/360) * grader
            double t = 2 * Math.PI * i / numberOfPoints;
            int x = (int) Math.round(originx + radius * Math.cos(t));
            int y = (int) Math.round(originy + radius * Math.sin(t));
// Husk at indstille radius til lidt mindre når offset x,y beregnes:
            int offsetX = (int) Math.round(originx + (offsetRadius) * Math.cos(t));
            int offsetY = (int) Math.round(originy + (offsetRadius) * Math.sin(t));


            Point2D_intw_degreeAnd_offset point =
                    new Point2D_intw_degreeAnd_offset(x, y, (float) Math.toDegrees(t), offsetX, offsetY);
//            System.out.println(Math.toDegrees(t));



            circleCoordinates[i] = point;
        }
        return circleCoordinates;
    }
//--------------------------------------------------------------------------------------------------------    
    private static final int NUMBEROFTEXTS = 2500;
    private static Point2D_int[] pointCoordinates = new Point2D_int[NUMBEROFTEXTS];

    public static void initCoordArray() {

        for (int x = 0; x < pointCoordinates.length; x++) {
            Point2D_int p = new Point2D_int((int) (Math.random() * 600), (int) (Math.random() * 600));
            pointCoordinates[x] = p;
        }
    }
    //--------------------------------------------------------------------------------------------------------    
    private static Point2D_int_wColor[] pointCoordinatesWColor = new Point2D_int_wColor[NUMBEROFTEXTS];

    public static void initCoordArrayWColor() {

        for (int x = 0; x < pointCoordinatesWColor.length; x++) {
            Point2D_int_wColor p = new Point2D_int_wColor(
                    new RandomFloatColor((float) Math.random(), (float) Math.random(), (float) Math.random()),
                    (int) (Math.random() * 600) - 300, (int) (Math.random() * 600) - 300);
            pointCoordinatesWColor[x] = p;
        }
    }
    //--------------------------------------------------------------------------------------------------------   

    public void updateMouseMovement(Point updatedMouseMovement) {
//        cameraPosX += (float)updatedMouseMovement.x;
//        System.out.println(mouseMovement.x + ", " + mouseMovement.y);
        cameraPosX += (float) updatedMouseMovement.x;
        cameraPosY += (float) updatedMouseMovement.y;

        System.out.println(updatedMouseMovement.x + ", " + updatedMouseMovement.y);

    }

    //--------------------------------------------------------------------------------------------------------    
    public static void drawCoordinateSys(GL2 gl) {

        gl.glLoadIdentity();
        gl.glBegin(GL2.GL_LINES);

        gl.glColor3f(1.0f, 0.0f, 0.0f);   // set the color of x
        gl.glVertex3f(-100, 0, 0);
        gl.glVertex3f(+100, 0, 0);

        gl.glColor3f(0.0f, 0.0f, 1.0f);   // set the color of y
        gl.glVertex3f(0, -100, 0);
        gl.glVertex3f(0, +100, 0);

        gl.glColor3f(0.0f, 1.0f, 0.0f);   // set the color of z
        gl.glVertex3f(0, 0, -100);
        gl.glVertex3f(0, 0, +100);

        gl.glEnd();
    }

    //--------------------------------------------------------------------------------------------------------    
    public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged) {
    }

    public void init(GLAutoDrawable gLDrawable) {
        GL2 gl = gLDrawable.getGL().getGL2();
        gl.glShadeModel(GLLightingFunc.GL_SMOOTH);
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClearDepth(1.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);

        gl.glDepthFunc(GL.GL_LEQUAL);
        gl.glHint(GL2ES1.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
        ((Component) gLDrawable).addKeyListener(this);

        // ------ MousecontrollerObject
//        ControllerMouseClickMovement controllerMouseClickMovement = new ControllerMouseClickMovement(this);
//
//        ((Component) gLDrawable).addMouseListener(controllerMouseClickMovement);
//        ((Component) gLDrawable).addMouseMotionListener(controllerMouseClickMovement);



    }

    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height) {
        GL2 gl = gLDrawable.getGL().getGL2();
        if (height <= 0) {
            height = 1;
        }
        float h = (float) width / (float) height;
        gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
        gl.glLoadIdentity();

        glu.gluPerspective(45.0f, h, 1.0, 1000.0);

        gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public void keyPressed(KeyEvent e) {

        if (e.getKeyCode() == KeyEvent.VK_Z) {

            indexNucleo1++;
//            cameraDistance += 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_A) {
            indexNucleo1--;
//            cameraDistance -= 3.0f;
        }

        if (e.getKeyCode() == KeyEvent.VK_X) {

            indexNucleo2++;
//            cameraDistance += 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_S) {
            indexNucleo2--;
//            cameraDistance -= 3.0f;
        }





        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            moveX += 13.f;
//            cameraPosX -= 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            moveX -= 13.f;
//            cameraPosX += 3.0f;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
//            cameraDistance -= 3.0f;
            scaleX = scaleX + 0.01f;
            scaleY = scaleY + 0.01f;

        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
//            cameraDistance += 3.0f;
            scaleX = scaleX - 0.01f;
            scaleY = scaleY - 0.01f;

        }

        if (e.getKeyCode() == KeyEvent.VK_PLUS) {
            rotateT += 0.1f;
        }

        if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
            exit();
        }




    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }

    public static void exit() {
        animator.stop();
        frame.dispose();
        System.exit(0);
    }

    public static void main(String[] args) {
        canvas.addGLEventListener(new Feymann_1cirkel2());
        frame.add(canvas);
        frame.setSize(800, 800);
//        frame.setUndecorated(true);
//        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                exit();
            }
        });


//        initCoordArray();


        initCoordArrayWColor();
        calculateCoordCircle(feynmannCircleOriginX, feynmannCircleOriginY, numberOfNucleotides, feynmannCircleRadius);

        calculateArcArray();


        frame.setVisible(true);
        animator.start();
        canvas.requestFocus();
    }

    public void dispose(GLAutoDrawable gLDrawable) {
        // do nothing
    }
}